const get = require('get-value');
const obj = { a: { b: { c: { d: 'foo' } } } };


console.log(get(obj, 'a.b.c.d'.split('.')));
console.log(get(obj, 'a'));


console.log('----------------- getValueV2 ------------------\n')
console.log(getValueV2(obj, 'a.b.c.d'.split('.')));
console.log(getValueV2(obj, 'a'));


function getValueV2(target, path, options) {

	if(!isPlainObject(options)) {
		options = {default: options}
	}

	// path 为number, function 时的处理
	if(typeof path ==='number') {
		path = String(path)
	}else if(typeof path === 'function') {
		path = path.call(this, target, options)
	}

	// 数组形式的路径
	const isArray = Array.isArray(path)
	const isString = typeof path === 'string'

	// 层级属性分隔符, 默认使用 '.'进行分隔
	const splitChar = options.separator || '.'
	const joinChar = options.joinChar || (typeof splitChar === 'string' ? splitChar : '.')

	if(!isString && !isArray) {
		return target
	}


	// 扩展split 
	let segs = isArray ? path : split(path, splitChar, options)

	let len = segs.length
	for (var idx = 0; idx < len; idx++) {
		let prop = segs[idx]

		if (typeof prop === 'number') {
	      prop = String(prop);
	    }

	    if (prop in target) {
	      	target = target[prop]
	    } else {
	    	break
	    }
	}

	if(idx === len) {
		return target
	}

	return options.default
}


/**
 * 是否为纯对象
 * @param  {[type]}  obj [description]
 * @return {Boolean}     [description]
 */
function isPlainObject(obj) {
	if (typeof obj !== 'object' || obj === null) return false

	proto = Object.getPrototypeOf(obj);
    if (!proto) {
        return true;
    }

    return obj.constructor === Object
}

/**
 * 扩展的split, 让getValue有机会获取 配置项 options中的split方法
 * @param  {[type]} path      [description]
 * @param  {[type]} splitChar [description]
 * @param  {[type]} options   [description]
 * @return {[type]}           [description]
 */
function split(path, splitChar, options) {
	if(typeof options.split === 'function') {
		return options.split(path)
	}
	return path.split(splitChar)
}
 